Skip to content

Add support for the JVM release option for scalac and javac - #170

Merged
armanbilge merged 9 commits into
typelevel:series/0.4from
vasilmkd:scalac-release
Feb 28, 2022
Merged

Add support for the JVM release option for scalac and javac#170
armanbilge merged 9 commits into
typelevel:series/0.4from
vasilmkd:scalac-release

Conversation

@vasilmkd

Copy link
Copy Markdown
Member

No description provided.

@armanbilge

Copy link
Copy Markdown
Member

I think this closes #79 :)

@armanbilge armanbilge linked an issue Feb 18, 2022 that may be closed by this pull request
@vasilmkd
vasilmkd marked this pull request as ready for review February 18, 2022 22:19
Comment thread settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala Outdated
Comment thread settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala Outdated
object autoImport {
lazy val tlFatalWarnings =
settingKey[Boolean]("Convert compiler warnings into errors (default: false)")
lazy val tlJvmRelease =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, bikeshed: why "jvm" vs "jdk"?

JDK seems to be what everyone else is saying e.g. in scala/scala#6362.

@armanbilge armanbilge Feb 18, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, interesting, javac uses JVM.

  --release <release>
        Compile for a specific VM version. Supported targets: 6, 7, 8, 9, 10, 11
  -target <release>            Generate class files for specific VM version

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to jdk.

armanbilge
armanbilge previously approved these changes Feb 18, 2022

@armanbilge armanbilge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay! Thank you :)

@vasilmkd
vasilmkd changed the base branch from series/0.4 to main February 18, 2022 23:01
@vasilmkd vasilmkd closed this Feb 18, 2022
@vasilmkd vasilmkd reopened this Feb 18, 2022
@armanbilge

Copy link
Copy Markdown
Member

I've been thinking about how we can get this PR in to the 0.4.x series. Since CI is running on JDK 8 anyway, I guess the point of this PR is to support projects that are published manually, from possibly newer JDKs?

If that's the case, I propose we actually don't set a default value for this setting. If this setting is not set, then no flags are added; but if it is set, it works exactly like you've got it here. So for the projects release manually this can be set to 8 as needed.

We can create a follow-up issue to default it to 8 when we break compat in the next minor bump.

WDYT?

@armanbilge

Copy link
Copy Markdown
Member

@vasilmkd sorry I have another question about this.

IIUC fs2 will have to set tlJdkRelease := 16 or something (at least for the fs2-io module). After it does that, will the generated jars still be consumable from older JVMs?

@vasilmkd

Copy link
Copy Markdown
Member Author

Nothing that's added here works for fs2 and essentially breaks it. We should put this on ice.

@armanbilge

Copy link
Copy Markdown
Member

Right, by ice you mean until the next breaking release, yes?

Fast-forwarding to then, I'm still concerned whether this works for fs2 at all.

@vasilmkd

Copy link
Copy Markdown
Member Author

It doesn't, if this ships, fs2 would have to disable all of it.

@armanbilge

Copy link
Copy Markdown
Member

So then maybe the setting should be an Option[Int]? Where None disables it?


override def globalSettings = Seq(
tlFatalWarnings := false,
tlJdkRelease := Some(8),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to be too annoying, but we can make this None and get this into series/0.4 :)

@vasilmkd

Copy link
Copy Markdown
Member Author

Yeah, sorry, I got distracted.

scalacOptions ++= {
val releaseOption = tlJdkRelease
.value
.map { release => if (isJava8) Seq.empty else Seq("-release", release.toString) }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the isJava8 check for scalacOptions?

Also, what is the failure mode if tlJdkRelease > 8 but java.version == 1.8?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If java.version == 1.8 it means we're running javac 1.8 which doesn't understand the --release flag. scalac somehow makes use of this and also fails compilation with

[error] '8' is not a valid choice for '-target'
[21](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:21)
[error] '8' is not a valid choice for '-target'
[22](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:22)
[error] bad option: '-target:8'
[23](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:23)
[error] bad option: '-target:8'
[24](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:24)
[error] (kernelJVM / Compile / compileIncremental) Compilation failed
[25](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:25)
[error] (kernelJS / Compile / compileIncremental) Compilation failed
[26](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:26)
[error] Total time: 13 s, completed Feb 16, 2022 11:57:41 AM
[27](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:27)

[28](https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true#step:12:28)
Error: Process completed with exit code 1.

from https://github.com/typelevel/cats-effect/runs/5215692131?check_suite_focus=true

@armanbilge armanbilge Feb 21, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, cool, that seems good. But if we don't add the flag, it won't protect us from a target JDK newer than the compile-time JDK since it basically ignores that setting, so it seems we need another check?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JDK 8 cannot target a newer JDK. Am I understanding your question correctly?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't specify anything, javac 1.8 compiles JVM 8 bytecode, 17 compiles JVM 17 bytecode, while scalac compiles JVM 8 bytecode.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies if I'm not reading your code correctly. Here's my hypothetical situation:

  1. tlJdkRelease := Some(17)
  2. I load my project in sbt on Java 8
  3. No release flags are added to scalacOptions, b/c java.version == 1.8
  4. My project compiles, even though I asked to target JDK 17.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a project is specifically targetting 17 and the code is compilable by JDK 8, I don't know why they're targetting 17 in the first place. 😆

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point :)

scalac can generate more optimized bytecode in certain situations when targeting newer JDKs.

Also, the fact that your project would fail to compile if you load it in Java 9 (but 8 would work!) is a bit odd imo :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vasilmkd
vasilmkd changed the base branch from main to series/0.4 February 21, 2022 20:41
@vasilmkd vasilmkd closed this Feb 21, 2022
@vasilmkd vasilmkd reopened this Feb 21, 2022
Comment thread settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala Outdated
}
case n =>
sys.error(
s"You're using JDK $n, which is not supported by `sbt-typelevel`. Please switch to a newer JDK.")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n is the target JDK right, not the user's runtime JDK?

Suggested change
s"You're using JDK $n, which is not supported by `sbt-typelevel`. Please switch to a newer JDK.")
s"Target JDK is $n, which is not supported by `sbt-typelevel`. Please select a JDK >= 8.")

@armanbilge

Copy link
Copy Markdown
Member

@vasilmkd looks like they are discussing renaming these flags in Scala 3.
https://contributors.scala-lang.org/t/improving-scala-3-forward-compatibility/5298/22

@armanbilge
armanbilge merged commit 43dc219 into typelevel:series/0.4 Feb 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add JDK target setting

2 participants